﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace FirefliesClustering
{
    class Program
    {
        //Считать вход -
        //N - количество векторов
        //Массив [N] векторов - пар координат
        //K - количество кластеров
        //
        //Запустить светлячковый алгоритм
        //На выходе - массив длины K - начальные центры кластеров                          *********
        //
        //Запустить от массива начальных центров алгоритм K-means
        //на выходе - Dictionary длины К списков вершин - кластеры. Ключи - центры кластеров
        static void Main(string[] path)
        {
            StreamReader file = File.OpenText(path[0]);

            //Данные для алгоритма светлячков.
            //===============================================================
            // Первая строка файла - всегда число векторов.
            int n = int.Parse(file.ReadLine()); 
            // Вторая строка файла - всегда число кластеров.
            int  k = int.Parse(file.ReadLine()); 
            //Количество светлячков
            int f = int.Parse(file.ReadLine()); 
            //Количество поколений
            int g = int.Parse(file.ReadLine()); 
            //Гамма-привлекательность
            float a = float.Parse(file.ReadLine());
            // vestors это массив размера n из двукоординатных векторов.
            Tuple<float, float>[] vectors = new Tuple<float, float>[n];
            //===============================================================
            
            string currentLine = string.Empty;
            int index = 0;
            while ((currentLine = file.ReadLine()) != null)
            {
                bool flag = true;

                float firstCoordinate = new float();
                float secondCoordinate = new float();

                for (int indexInLine = 0; indexInLine < currentLine.Length; indexInLine++)
                {
                    int sing = 1;
                    int degree = 0;
                    float currentNumber = 0;
                    while (indexInLine < currentLine.Length && currentLine[indexInLine] != ' ')
                    {
                        if (currentLine[indexInLine] == '-')
                        {
                            sing = -1;
                            indexInLine++;
                        }
                        else
                        {
                                currentNumber = currentNumber + float.Parse(currentLine[indexInLine].ToString()) * (float)Math.Pow(10, degree);
                                degree++;
                                indexInLine++;                      
                            
                        }
                    }
                    currentNumber = float.Parse(Reverse((currentNumber).ToString())) * sing;
                    if (flag)
                    {
                        firstCoordinate = currentNumber;
                        flag = false;
                    }
                    else
                    {
                        secondCoordinate = currentNumber;
                    }
                }

                Tuple<float, float> newVector = new Tuple<float, float>(firstCoordinate, secondCoordinate);
                vectors[index] = newVector;
                index++;
            }
            
            /*Tuple<float,float>[] testArray = new Tuple<float,float>[2];
            testArray[0] = new Tuple<float,float>(-2,-3);
            testArray[1] = new Tuple<float,float>(3,5);*/
            
            
           // List<Tuple<Tuple<float, float>, List<Tuple<float, float>>>> answer = KMeans.DoTheClustering(testArray, vectors);

            List<Tuple<Tuple<float, float>, List<Tuple<float, float>>>> answer = KMeans.DoTheClustering(Firefly.MakeCentroids(vectors, k, f, g, a), vectors);


            //Вывод на экран
            int p = 0;
            foreach (Tuple<Tuple<float, float>, List<Tuple<float, float>>> line in answer)
            {
                Console.WriteLine("Cluster number {0} with a center in ({1} , {2}) includes vectors {3}", p, line.Item1.Item1, line.Item1.Item2, PrintListOfTuples(line.Item2));
                p++;
            }

            Console.ReadKey();
        }

        private static string Reverse(string s)
        {
            char[] charArray = s.ToCharArray();
            Array.Reverse(charArray);
            return new string(charArray);
        }

        private static string PrintListOfTuples(List<Tuple<float, float>> list)
        {
            string result = "\n";

            foreach (Tuple<float, float> vector in list)
            {
                result = result + "(" + vector.Item1 + " , " + vector.Item2 + ")" + "\n";
            }

            return result;
        }
    }
}
